package com.ngsky.ana.index;

import com.ngsky.ana.conf.AppConstants;
import com.ngsky.ana.detail.ColorItem;
import com.ngsky.ana.server.AnalyzeServer;
import com.ngsky.ana.server.AnalyzeTask;
import com.ngsky.ana.utils.DateUtil;
import com.ngsky.ana.utils.ImageUtil;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.filechooser.FileSystemView;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.ngsky.ana.conf.AppConstants.*;
import static com.ngsky.ana.server.AnalyzeServer.COLOR_SIZE;
import static com.ngsky.ana.server.AnalyzeServer.fd;

/**
 * @Author syx
 * @Desc
 * @Create 2020/6/14 14:50
 */
public class Index extends JFrame {
    private ImageList imageList;
    private List<ImageItem> itemList;

    public Index() {
        initUI();
    }

    /**
     * 初始化UI
     */
    private void initUI() {
        // 初始化窗口
        setSize(WINDOW_W, WINDOW_H);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setResizable(false);

        initMenu();

        setVisible(true);
    }

    /**
     * 初始化菜单
     */
    private void initMenu() {
        Font normalFont = new Font(null, Font.PLAIN, 20);

        // 初始化菜单
        JMenuBar menuBar = new JMenuBar();

        JMenu fileMenu = new JMenu("文件");
        fileMenu.setFont(normalFont);

        menuBar.add(fileMenu);
        JMenuItem openMenuItem = new JMenuItem("打开");
        openMenuItem.setFont(normalFont);

        JMenuItem exportMenuItem = new JMenuItem("导出");
        exportMenuItem.setFont(normalFont);

        JMenuItem exitMenuItem = new JMenuItem("退出");
        exitMenuItem.setFont(normalFont);

        fileMenu.add(openMenuItem);
        fileMenu.addSeparator();
        fileMenu.add(exportMenuItem);
        fileMenu.addSeparator();
        fileMenu.add(exitMenuItem);

        JMenu setMenu = new JMenu("设置");
        setMenu.setFont(normalFont);

        menuBar.add(setMenu);
        JMenuItem historyMenuItem = new JMenuItem("历史记录");
        historyMenuItem.setFont(normalFont);

        JMenuItem savedirMenuItem = new JMenuItem("存储路径");
        savedirMenuItem.setFont(normalFont);

        setMenu.add(historyMenuItem);
        setMenu.addSeparator();
        setMenu.add(savedirMenuItem);

        JMenu aboutMenu = new JMenu("关于");
        aboutMenu.setFont(normalFont);

        menuBar.add(aboutMenu);
        JMenuItem aboutMenuItem = new JMenuItem("悦复科技");
        aboutMenuItem.setFont(normalFont);
        aboutMenu.add(aboutMenuItem);

        setJMenuBar(menuBar);

        // 添加菜单监听事件处理
        // 菜单事件监听器
        final Component parent = this;
        // 设置 "打开" 子菜单被点击的监听器
        openMenuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("打开  被点击");
                showFileOpenDialog(parent);
            }
        });
        savedirMenuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("存储路径 被点击");
                showSaveDirDialog();
            }
        });
        historyMenuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("历史记录 被点击");
                showHistoryDialog();
            }
        });
        exitMenuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("退出 被点击");
                System.exit(0);
            }
        });
    }

    /*
     * 打开文件
     */
    private void showFileOpenDialog(Component parent) {
        // 创建一个默认的文件选取器
        JFileChooser fileChooser = new JFileChooser();

        // 设置默认显示的文件夹为当前文件夹
        FileSystemView fsv = FileSystemView.getFileSystemView();
        fileChooser.setCurrentDirectory(fsv.getHomeDirectory());

        // 设置文件选择的模式（只选文件、只选文件夹、文件和文件均可选）
        fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
        // 设置是否允许多选
        fileChooser.setMultiSelectionEnabled(true);

        // 添加可用的文件过滤器（FileNameExtensionFilter 的第一个参数是描述, 后面是需要过滤的文件扩展名 可变参数）
//        fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("zip(*.zip, *.rar)", "zip", "rar"));
        // 设置默认使用的文件过滤器
        fileChooser.setFileFilter(new FileNameExtensionFilter("image(*.jpg, *.png, *.gif)", "jpg", "png", "gif"));

        // 打开文件选择框（线程将被阻塞, 直到选择框被关闭）
        int result = fileChooser.showOpenDialog(parent);

        if (result == JFileChooser.APPROVE_OPTION) {
            // 如果点击了"确定", 则获取选择的文件路径
//            File file = fileChooser.getSelectedFile();

            // 如果允许选择多个文件, 则通过下面方法获取选择的所有文件
            File[] files = fileChooser.getSelectedFiles();
            if (null != files && files.length > 0) {
                // 初始化首页滚动面板
                itemList = new ArrayList<ImageItem>();
                for (int i = 0; i < files.length; i++) {
                    File f = files[i];
                    ImageItem ii = new ImageItem(f.getPath());

                    final String filePath = f.getPath();
                    ii.addMouseListener(new MouseAdapter() {
                        public void mouseClicked(MouseEvent me) {
                            System.out.println("图片点击事件...:" + filePath);
                            showDetailDialog(filePath);
                        }
                    });

                    itemList.add(ii);

                    // 启动新线程分析图片
                    Thread thread = new Thread(new AnalyzeTask(files.length, i, f.getPath()));
                    thread.start();
                }
                imageList = new ImageList(itemList);
                JScrollPane scrollPane = new JScrollPane(imageList, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
                scrollPane.setPreferredSize(new Dimension(WINDOW_W, WINDOW_H));
                scrollPane.getVerticalScrollBar().setUnitIncrement(20);

                setContentPane(scrollPane);
                setVisible(true);
            }
        }
    }

    /**
     * 显示分析详情
     */
    private void showDetailDialog(String filePath) {
        try {
            // 创建一个模态对话框
            final JDialog dialog = new JDialog(this, "图片分析", true);
            // 设置对话框的宽高
            dialog.setSize(WINDOW_W, WINDOW_H-200);
            // 设置对话框大小不可改变
            dialog.setResizable(false);
            // 设置对话框相对显示的位置
            dialog.setLocationRelativeTo(this);

            // 创建图片预览器
            JPanel imgPan = new JPanel();

            JLabel imgLabel = new JLabel(ImageUtil.getFileName(filePath));
            BufferedImage buff = ImageIO.read(new FileInputStream(filePath));
            buff = ImageUtil.thumbnail(buff, 600, 600);
            imgLabel.setIcon(new ImageIcon(buff));
            imgLabel.setHorizontalTextPosition(SwingConstants.CENTER);   // 水平方向文本在图片中心
            imgLabel.setVerticalTextPosition(SwingConstants.BOTTOM);     // 垂直方向文本在图片下方
            imgLabel.setPreferredSize(new Dimension(600, 600));

            imgPan.add(imgLabel);

            // 分析结果
            final Component anaPanel = colorCard(filePath);

            final Box contentBox = Box.createVerticalBox();
            contentBox.add(imgLabel);
            contentBox.add(anaPanel);

            // 导出按钮
            final JButton exportBtn = new JButton("导出");
            exportBtn.setPreferredSize(new Dimension(400, 50));
            exportBtn.setOpaque(true);
            exportBtn.setBackground(Color.GREEN);
            exportBtn.setForeground(Color.WHITE);
            exportBtn.setFont(new Font(null, Font.PLAIN, 20));
            exportBtn.setBorderPainted(false);

            exportBtn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    System.out.println("导出按钮被点击");
                    BufferedImage image = new BufferedImage(contentBox.getWidth()*2, contentBox.getHeight()*2, BufferedImage.TYPE_INT_RGB);
                    Graphics2D g = image.createGraphics();
                    contentBox.printAll(g);
                    g.dispose();
                    try {
                        ImageIO.write(image, "png", new File(get(DB_K_SAVEDIR) + "\\exp_" + System.currentTimeMillis() + ".png"));
                    } catch (IOException exp) {
                        exp.printStackTrace();
                    }
                }
            });

            JPanel btnPan = new JPanel();
            btnPan.add(exportBtn);

            Box vBox = Box.createVerticalBox();
            vBox.setSize(WINDOW_W, WINDOW_H - 200);
            vBox.add(contentBox);
            vBox.add(btnPan);

            // 设置对话框的内容面板
            dialog.setContentPane(vBox);
            // 显示对话框
            dialog.setVisible(true);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 详情-标准色卡板
     */
    private Component colorCard(String filePath) {
        GridLayout layout = new GridLayout(3, 3);

        JPanel panel = new JPanel(layout);

        try {
            // 持续 60 秒检查文件中是否存在 否则重新生成
            int retry = 100;
            int retrySeconds = 500;
            String dirPath = AppConstants.getDBPath() + "\\" + DateUtil.getMonth(new Date());
            String saveFile = dirPath + "\\" + "." + filePath.hashCode();
            String[] color = null;
            for (int i = 0; i < retry; i++) {
                color = ImageUtil.readDb(saveFile);
                if (null == color) {
                    Thread.sleep(retrySeconds);
                    continue;
                } else {
                    break;
                }
            }

            if (null == color) {
                System.out.println("retry analyze img...");
                AnalyzeServer server = new AnalyzeServer();
                double[] tmp = server.analyze(filePath);
                for (int i = 0; i < COLOR_SIZE; i++) {
                    String cv = fd(tmp[i] * 100) + "%";
                    if ("0%".equals(cv)) {
                        continue;
                    }
                    AnalyzeServer.WhoColor whoColor = AnalyzeServer.WhoColor.get(i);
                    if (null != whoColor) {
                        ColorItem item = new ColorItem(whoColor.getIn(), whoColor.getIc(), cv);
                        panel.add(item);
                    }
                }
            } else {
                System.out.println("get analyze from file...");
                for (int i = 0; i < COLOR_SIZE; i++) {
                    String cv = color[i];
                    if ("0".equals(cv)) {
                        continue;
                    }
                    AnalyzeServer.WhoColor whoColor = AnalyzeServer.WhoColor.get(i);
                    if (null != whoColor) {
                        ColorItem item = new ColorItem(whoColor.getIn(), whoColor.getIc(), cv);
                        panel.add(item);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return panel;
    }

    /**
     * 设置存储路径对话框
     */
    private void showSaveDirDialog() {
        // 创建一个模态对话框
        final JDialog dialog = new JDialog(this, "存储路径", true);
        // 设置对话框的宽高
        dialog.setSize(600, 100);
        // 设置对话框大小不可改变
        dialog.setResizable(false);
        // 设置对话框相对显示的位置
        dialog.setLocationRelativeTo(this);

        JPanel panel = new JPanel();

        // 创建文本框，指定可见列数为8列
        final JTextField textField = new JTextField(20);
        textField.setText(get(DB_K_SAVEDIR));
        textField.setFont(new Font(null, Font.PLAIN, 20));

        // 创建一个按钮，点击后获取文本框中的文本
        JButton btn = new JButton("浏览");
        btn.setFont(new Font(null, Font.PLAIN, 20));
        btn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("浏览: " + textField.getText());
                chooseSaveDir(dialog, textField);
            }
        });
        panel.add(textField);
        panel.add(btn);

        dialog.setContentPane(panel);
        dialog.setVisible(true);
    }

    /**
     * 存储路径选择文件夹
     */
    private void chooseSaveDir(Component parent, JTextField textField) {
        // 创建一个默认的文件选取器
        JFileChooser fileChooser = new JFileChooser();

        // 设置默认显示的文件夹为当前文件夹
        FileSystemView fsv = FileSystemView.getFileSystemView();
        fileChooser.setCurrentDirectory(fsv.getHomeDirectory());

        // 设置文件选择的模式（只选文件、只选文件夹、文件和文件均可选）
        fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        // 设置是否允许多选
        fileChooser.setMultiSelectionEnabled(false);

        // 打开文件选择框（线程将被阻塞, 直到选择框被关闭）
        int result = fileChooser.showOpenDialog(parent);

        if (result == JFileChooser.APPROVE_OPTION) {
            try {
                // 如果点击了"确定", 则获取选择的文件路径
                File file = fileChooser.getSelectedFile();
                System.out.println("选中路径：" + file.getPath());
                AppConstants.insert(DB_K_SAVEDIR, file.getPath());
                textField.setText(file.getPath());
                textField.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 打开历史记录列表
     */
    private void showHistoryDialog() {
        // 创建一个模态对话框
        final JDialog dialog = new JDialog(this, "历史记录", true);
        // 设置对话框的宽高
        dialog.setSize(WINDOW_W, WINDOW_H - 140);
        // 设置对话框大小不可改变
        dialog.setResizable(false);
        // 设置对话框相对显示的位置
        dialog.setLocationRelativeTo(this);

        dialog.setContentPane(new HistoryList(this));
        dialog.setVisible(true);
    }
}
